package cn.hrfax.stf.sdk.integration.abs;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;

import cn.hrfax.stf.sdk.constant.CommonConstant;
import cn.hrfax.stf.sdk.constant.RemoteUrlConstant;
import cn.hrfax.stf.sdk.model.CarLoanEncryptRequest;
import cn.hrfax.stf.sdk.model.LoanPreRequest;
import cn.hrfax.stf.sdk.model.Pub;
import cn.hrfax.stf.sdk.model.RemoteResponse;
import cn.hrfax.stf.sdk.util.DES3Util;
import cn.hrfax.stf.sdk.util.HttpUtil;
import cn.hrfax.stf.sdk.util.RSASignature;
import cn.hrfax.stf.sdk.util.RSAUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 车贷
 * @author yongSen.wang
 * @date 2020/6/15 16:24
 */
@Slf4j
@Service
public abstract class AbstractCarRemote extends AbstractRemote {

    @Override
    protected <P> RemoteResponse getRemoteResult(String urlPath, String orderNo, P req,
                                                 String busiCode) {
        /**1.  加密前请求报文*/
        LoanPreRequest preRequest = buildPreRequest(req, orderNo, busiCode);
        /**2. 加密请求报文进行签名*/
        CarLoanEncryptRequest encryptRequest = buildEncryptRequest(preRequest, busiCode);
        /**3.HTTP或者HTTPS post请求*/
        String drUrlCommonPrefix = RemoteUrlConstant.DR_URL_COMMON_PREFIX;
        String requestUrl = drUrlCommonPrefix + urlPath;
        String params = JSON.toJSONString(encryptRequest);
        String responseStr = HttpUtil.doPost(requestUrl, params, CommonConstant.CHARSET_UTF_8);
        if (StringUtils.isBlank(responseStr)) {
            throw new RuntimeException("无响应数据返回!");
        }

        log.info("responseStr:{}", responseStr);

        return JSON.parseObject(responseStr, RemoteResponse.class);
    }

    /**
     * 组装加密前请求报文
     * @param paramsObject
     * @param orderNo
     * @param busiCode
     * @return
     */
    private LoanPreRequest buildPreRequest(Object paramsObject, String orderNo, String busiCode) {
        Pub pub = new Pub();
        pub.setBankCode(CommonConstant.BANK_CODE);
        pub.setAssurerNo(CommonConstant.ASSURER_NO);
        pub.setPlatNo(CommonConstant.PLAT_NO);
        pub.setBusiCode(busiCode);
        pub.setProductType(CommonConstant.PRODUCT_TYPE);
        pub.setOrderNo(orderNo);

        LoanPreRequest request = new LoanPreRequest();
        request.setPub(pub);
        request.setReq(paramsObject);

        return request;
    }

    /**
     * 组装加密请求报文
     *
     * @param reqData  业务请求参数,json格式，依据不同接口传送不同的值
     * @param busiCode
     * @return
     */
    private CarLoanEncryptRequest buildEncryptRequest(Object reqData,
                                                      String busiCode) throws RuntimeException {
        try {
            String publicKey = CommonConstant.PUBLIC_KEY;
            String privateKey = CommonConstant.PRIVATE_KEY;
            //加密
            String encryptContent = RSAUtil.encrypt(JSON.toJSONString(reqData), publicKey);
            //加签
            String signContent = RSASignature.sign(JSON.toJSONString(reqData), privateKey);
            CarLoanEncryptRequest request = new CarLoanEncryptRequest();
            request.setAssurerNo(CommonConstant.ASSURER_NO);
            request.setData(encryptContent);
            request.setSign(signContent);
            request.setBankType(CommonConstant.BANK_TYPE);
            request.setBusiCode(busiCode);
            request.setPlatNo(CommonConstant.PLAT_NO);

            return request;
        } catch (Exception ex) {
            log.error("组装加密请求报文异常");
            throw new RuntimeException("组装加密请求报文异常");
        }
    }
}